#pragma once

#include "Socket.hpp"
#include <functional>
#include <sys/wait.h>

using ioservice_t = std::function<void(std::shared_ptr<Socket>&, const InetAddr&)>;

class TcpServer : public NoCopy
{
public:
    TcpServer(uint16_t port)
        : _listen_socket(std::make_unique<TcpSocket>())
        , _running(false)
    {   
        // 1. 创建套接字
        // 2. bind套接字
        // 3. 设置监听套接字
        _listen_socket->BuildTcpServer(port);
    }

    // version-多进程
    void Start(ioservice_t service)
    {
        _running = true;

        while (_running)
        {
            // 4. 创建已连接套接字
            InetAddr client;
            std::shared_ptr<Socket> sockfd = _listen_socket->Accept(&client);
            if(!sockfd)
                continue;

            pid_t pid = fork();
            if(pid < 0)
            {
                LOG(LogLevel::WARNING) << "fork failed";
                continue;
            }
            else if(pid == 0)
            {
                _listen_socket->Close(); // 关闭listen_sockfd
                // 子进程
                if(fork() > 0)
                    exit(OK);
                // 孙子进程
                service(sockfd,client);
                exit(OK);
            }
            else
            {
                sockfd->Close(); // 关闭sockfd
                // 父进程
                waitpid(pid,nullptr,0);
            }
        }
    }

private:
    std::unique_ptr<Socket> _listen_socket;
    bool _running;
};